#ifndef _SRC_SERVER_BLOG_SERVER_H_
#define _SRC_SERVER_BLOG_SERVER_H_

#include <cstdint>
#include <string>

#include <cereal/cereal.hpp>
#include <cereal/types/string.hpp>

#include "src/base/utils.h"
#include "src/net/http/http_server.h"
#include "src/net/http/http_response.h"
#include "src/net/event_loop.h"
#include "src/server/blog_cacher.h"

namespace fio66 {

struct BlogServerConfig {
  std::string uri_path;
  uint16_t thread_num;
  uint16_t port;
};

template <class Archive>
void serialize(Archive& ar, BlogServerConfig& blog_config) {
  ar(
     cereal::make_nvp("uri_path", blog_config.uri_path),
     cereal::make_nvp("thread_num", blog_config.thread_num),
     cereal::make_nvp("port", blog_config.port));
}

class BlogServer {
 public:
  DISALLOW_COPY_AND_ASSIGN(BlogServer)
  BlogServer(BlogServerConfig config, net::EventLoop* event_loop);
  ~BlogServer() = default;
  bool Start();

 private:
  void OnConnect(const net::HttpRequest& request, net::HttpResponse* response);
  bool CheckRequestValid(const net::HttpRequest& request);
  void SendHttpMsg(net::HttpResponse* response, const fio66::net::HttpStatusCode code, std::string_view body = "");
  std::shared_ptr<BlogCacher::FileInfo> TryToFindFileConeten(const net::HttpRequest& request);

 private:
  bool start_ = false;
  BlogServerConfig config_;
  BlogCacher cacher_;
  net::HttpServer http_server_;
};

}  // namespace fio66

#endif  // _SRC_SERVER_BLOG_SERVER_H_
